#include "main.h"

/* Static file pointer for log file operations, initialized to NULL for safety */
static FILE *LOG_FILE = NULL;

/* Global variable to define the current logging threshold level for message filtering */
logLevelEnum log_level = MSG_INFO;

/**
 * @brief Create and initialize log file for writing application logs
 * This function attempts to create or open an existing log file with append mode,
 * ensuring that previous log entries are preserved while allowing new entries
 * @param path: String containing the filesystem path where log file should be created
 * @return uint8_t Returns TRUE if file creation succeeded, FALSE if any step failed
 */
static uint8_t log_createFile(const char *path)
{
    /* Validate input parameter to ensure path is not NULL before proceeding */
    if (path == NULL)
    {
        printf("path is NULL\n");
        return FALSE;
    }
    
    /* Check if the file exists and has read/write permissions using access system call */
    /* This verification prevents issues with file operations due to permission problems */
    if (access(path, R_OK | W_OK) == -1) {
        /* Print error message to standard error stream for permission or access issues */
        fprintf(stderr, "Error accessing %s: ", path);
        return FALSE;
    }

    /* Open the log file in append mode to preserve existing content while allowing new writes */
    /* "a+" mode ensures file is created if it doesn't exist and positions at end for appending */
    LOG_FILE = fopen(path, "a+");
    
    /* Verify that file opening operation was successful before proceeding */
    if (LOG_FILE == NULL)
    {
        /* Notify user that log file creation failed and logging will use standard output */
        printf("log_open_file: failed to open %s log file, using standard output\n", path);
        return FALSE;
    }

    /* Return success status indicating log file was successfully created and opened */
    return TRUE;
}

/**
 * @brief Safely close the log file and clean up file pointer
 * This function ensures proper resource cleanup by closing the file handle
 * and resetting the global file pointer to prevent use-after-close errors
 */
void log_closeFile(void)
{
    /* Check if file pointer is valid before attempting close operation */
    if (LOG_FILE != NULL) {
        /* Flush any buffered data to disk and release file handle resources */
        fclose(LOG_FILE);
        /* Set file pointer to NULL to prevent dangling pointer and double-free issues */
        LOG_FILE = NULL; 
    }
}

/**
 * @brief Retrieve the current size of specified file in bytes
 * This function uses stat system call to get file metadata including size information
 * @param path: String containing filesystem path to the target file
 * @return int Returns file size in bytes, or -1 if stat operation fails
 */
int getFileSize(const char *path)
{
    /* Structure to hold file statistics including size, permissions, and timestamps */
    struct stat statbuf;
    
    /* Populate stat structure with file metadata, returning -1 on failure */
    stat(path, &statbuf);
    
    /* Extract file size in bytes from the stat structure for return to caller */
    int size = statbuf.st_size;

    /* Return the file size value to the calling function for further processing */
    return size;
}

/**
 * @brief Delete and recreate log file to reset log content
 * This function provides log rotation capability by clearing existing log content
 * while maintaining the same file handle for continued logging operations
 * @param path: String containing filesystem path to the log file for deletion
 * @return int Returns TRUE if file recreation succeeded, FALSE if any operation failed
 */
int delFile(const char *path)
{
    /* Close current log file handle to ensure no data loss during deletion process */
    log_closeFile();             
    
    /* Open file in write mode which truncates existing content to zero length */
    /* This effectively deletes all previous log entries while keeping file handle */
    LOG_FILE = fopen(path, "w"); 
    
    /* Close the truncated file to complete the deletion and cleanup process */
    log_closeFile();             

    /* Recreate log file in append mode to prepare for new log entries */
    if (!log_createFile(path))
    {
        /* Notify user if log file recreation failed after deletion attempt */
        printf("log_createFile error!\n");
        return FALSE;
    }
    
    /* Return success status indicating file was successfully deleted and recreated */
    return TRUE;
}

/**
 * @brief Format and write log messages to file with timestamp and level filtering
 * This is the primary logging function that handles message formatting, timestamp
 * generation, and log level filtering before writing to the output file
 * @param level: Log level enumeration value determining message importance threshold
 * @param fmt: Format string specifying the structure of the log message (printf-style)
 * @param ...: Variable arguments list matching the format string specifications
 */
void log_printf(logLevelEnum level, const char *fmt, ...)
{
    /* Define maximum log file size threshold for automatic log rotation (10KB) */
    int size = 10 * 1024; 
    
    /* Variable argument list structure for handling printf-style format arguments */
    va_list ap;
    
    /* Time structure pointer for breaking down timestamp into human-readable components */
    struct tm *pTM;
    
    /* Time variable storing seconds since epoch for current timestamp generation */
    time_t nSeconds;

    /* Initialize variable argument list processing using the format string */
    va_start(ap, fmt);

    /* Commented out automatic log rotation based on file size - available for future use */
    // if (getFileSize(LOG_PATH) > size)
    // {
    //     delFile(LOG_PATH);
    // }

    /* Check if logging is enabled globally and log file handle is valid before proceeding */
    if ((log_status_get()) && (LOG_FILE))
    {
        /* Apply log level filtering - only process messages meeting minimum level threshold */
        if (level >= log_level)
        {
            /* Get current system time in seconds since epoch for timestamp generation */
            time(&nSeconds);
            
            /* Convert epoch time to local time structure for human-readable formatting */
            pTM = localtime(&nSeconds);

            /* Write formatted timestamp prefix to log file with date and time components */
            /* Year needs 1900 adjustment, month needs +1 adjustment from struct tm values */
            fprintf(LOG_FILE, "%4d-%02d-%02d %02d:%02d:%02d ", pTM->tm_year + 1900, pTM->tm_mon + 1, pTM->tm_mday,
                    pTM->tm_hour, pTM->tm_min, pTM->tm_sec);

            /* Write the actual log message content using variable argument formatting */
            vfprintf(LOG_FILE, fmt, ap);
        }
    }
    
    /* Clean up variable argument list to prevent memory leaks and undefined behavior */
    va_end(ap);
}

/**
 * @brief Initialize logging subsystem and prepare for log message processing
 * This function performs the initial setup required for the logging system
 * including file creation and configuration validation
 * @return uint8_t Returns TRUE if initialization succeeded, FALSE if any step failed
 */
uint8_t log_manageInit(void)
{
    /* Commented out automatic log file creation - can be enabled for file-based logging */
    // if (!log_createFile(LOG_PATH))
    // {
    //     printf("log_createFile error!\n");
    //     return FALSE;
    // }

    /* Return success status indicating logging subsystem is ready for operation */
    return TRUE;
}